package com.itheima.pinda.file.biz;

import cn.hutool.core.util.StrUtil;
import com.itheima.pinda.file.domain.FileDO;
import com.itheima.pinda.file.entity.Attachment;
import com.itheima.pinda.file.enumeration.DataType;
import com.itheima.pinda.file.utils.ZipUtils;
import com.itheima.pinda.utils.NumberHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 文件下载具体处理逻辑
 *
 * @author:ivan.liu
 */
@Component
@Slf4j
public class FileBiz {

    /**
     * 构建下载文件的新文件名
     * @param fileName
     * @param order
     * @return
     */
    private static String buildNewFileName(String fileName,Integer order){
        return StrUtil.strBuilder(fileName).insert(fileName.lastIndexOf("."),"("+order+")").toString();
    }

    /**
     * 进行文件下载
     * @param fileDOList
     * @param request
     * @param response
     */
    public void down(List<FileDO> fileDOList, HttpServletRequest request, HttpServletResponse response) throws Exception {
        //计算需要下载文件大小
        int fileSize = fileDOList.stream().filter(fileDO -> fileDO != null && !fileDO.getDataType().eq(DataType.DIR) && StringUtils.isNoneEmpty(fileDO.getUrl()))
                .mapToInt(fileDO -> NumberHelper.intValueOf0(fileDO.getSize()))
                .sum();
        //设置需要下载文件的名称
        String downLoadFileName = fileDOList.get(0).getSubmittedFileName();
        if (fileDOList.size()>1){
            //需要下载的文件超过1个，生成压缩文件
            downLoadFileName = StringUtils.substring(downLoadFileName, 0, StringUtils.lastIndexOf(downLoadFileName, "."))
            +"等.zip";
        }
        Map<String,String> fileMap = new LinkedHashMap<>(fileDOList.size());
        //处理命名重复
        Map<String,Integer> duplicateFile = new HashMap<>(fileDOList.size());
        fileDOList.stream().filter(fileDO -> fileDO != null && !fileDO.getDataType().eq(DataType.DIR) && StringUtils.isNoneEmpty(fileDO.getUrl()))
                .forEach(fileDO -> {
                    //获取原始文件名
                    String submittedFileName = fileDO.getSubmittedFileName();
                    //判断名称是否重复
                    if (fileMap.containsKey(submittedFileName)){
                        if (duplicateFile.containsKey(submittedFileName)){
                            Integer count = duplicateFile.get(submittedFileName);
                            duplicateFile.put(submittedFileName,++count);
                        }else {
                            duplicateFile.put(submittedFileName,1);
                        }
                        submittedFileName = buildNewFileName(submittedFileName,duplicateFile.get(submittedFileName));
                    }
                    fileMap.put(submittedFileName,fileDO.getUrl());
                });
        ZipUtils.zipFilesByInputStream(fileMap,Long.valueOf(fileSize),downLoadFileName,request,response);
    }
}
